package com.onpositive.wikistorage;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.onpositive.mediawiki.propertyparser.ParsedCategory;
import com.onpositive.mediawiki.propertyparser.ParsedDocument;
import com.onpositive.units.ParsedProperty;
import com.onpositive.units.ParsedValue;

public class PropertyAnalyzer {
	
	public static String PROPERY_ANALIZE_SUBFOLDER_PATH = "property analize\\" ;
	public static String PROPERY_ANALIZE_SUMMARY_FILE_NAME = "!!!Summary.txt" ;
	
	
	public PropertyAnalyzer(){}
	String rootPath ;
	private DocumentBuilder builder ;
	private Element root;
	private Document document ;
	private FileOutputStream summaryFile ;
	private HashMap<String,PropertyStats> statsMap = new HashMap<String,PropertyStats>() ; 

	
	
	public HashMap<String, PropertyStats> getStatsMap() {
		return statsMap;
	}

	public void performTest( String rootPath )
	{
		init( rootPath ) ;		
		collectStats( root );		
		flush();
	}

	public void flush() {
		ArrayList<PropertyStats>nl=new ArrayList<PropertyStats>( statsMap.values() );
		Collections.sort(nl,new Comparator<PropertyStats>() {

			@Override
			public int compare(PropertyStats o1, PropertyStats o2) {
				return o1.getUseCount()-o2.getUseCount();
			}
		});
		
		File f = new File( rootPath + PROPERY_ANALIZE_SUBFOLDER_PATH ) ;
		f.mkdir() ;
		
		try {
			summaryFile = new FileOutputStream( new File( rootPath + 
														  PROPERY_ANALIZE_SUBFOLDER_PATH + 
														  PROPERY_ANALIZE_SUMMARY_FILE_NAME) );
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return ;
		}
		
		for( PropertyStats ps : nl )
		{
			ps.flushStats( summaryFile );
			ps.flushUndefFiles( rootPath + PROPERY_ANALIZE_SUBFOLDER_PATH ) ;
		}
		
		close() ;
	}

	public void collectStats( Element _root ) {
		
		NodeList fileNodes = _root.getChildNodes() ;
		int filesCount = fileNodes.getLength() ;		
		
		for( int i = 0 ; i < filesCount ; i++ )
		{
			Node node = fileNodes.item(i) ;
			Element fileElement ;
			if( node instanceof Element ){
				fileElement = (Element)node ;
				processFileElement( fileElement ) ;
			}			
		}
	}
	
	private void processFileElement( Element fileElement )
	{
		String fileName = fileElement.getAttribute("filename") ;
		
		NodeList properyNodes = fileElement.getChildNodes() ;
		int propertiesCount = properyNodes.getLength() ;		
		
		for( int i = 0 ; i < propertiesCount ; i++ )
		{
			Node node = properyNodes.item(i) ;
			Element propertyElement ;
			if( node instanceof Element ){
				propertyElement = (Element)node ;
				processPropertyElement( propertyElement, fileName ) ;
			}			
		}	
						
	}
	
	private void processPropertyElement( Element propertyElement, String fileName ) 
	{
		String name  = propertyElement.getAttribute("name" ) ;
		String type  = propertyElement.getAttribute("type" ) ;
//		String unit  = propertyElement.getAttribute("unit" ) ;
		String value = propertyElement.getAttribute("value") ;
		
		PropertyStats stats = this.statsMap.get( name ) ;
		if( stats == null )
		{
			stats = new PropertyStats( name );
			statsMap.put( name, stats ) ;
		}
		stats.incrementFilesCount() ;
		stats.incrementTypeUsageCount(type) ;
		if( type.equals("undef") )
			stats.addUndefFile( fileName, value ) ;		
	}
	public void processParsedCategory( ParsedCategory cat )
	{
		for( ParsedDocument pDoc : cat.getDocumentsList() )
			processParsedDocument(pDoc) ;
	}
	
	private void processParsedDocument( ParsedDocument pDoc )
	{
		String fileName = pDoc.getName() ;
		
		for( ParsedProperty prop : pDoc.getProps().values() )
		{
			String name  = prop.getName() ;
			PropertyStats stats = this.statsMap.get( name ) ;
			if( stats == null )
			{
				stats = new PropertyStats( name );
				statsMap.put( name, stats ) ;
			}			
			
			for( ParsedValue val : prop.getValues() )
			{
				String type  = val.getId() ;
//				String unit  = propertyElement.getAttribute("unit" ) ;
				String value = val.getValueAsString() ;				
			
				stats.incrementFilesCount() ;
				stats.incrementTypeUsageCount(type) ;
				if( type.equals("undef") )
					stats.addUndefFile( fileName, value ) ;
			}
		}	
						
	}
	
	private void init( String _rootPath )
	{
	

	}
	
	private void close()
	{
		try {
			summaryFile.close() ;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private DocumentBuilder constructBuilder()
	{		
		try {
			return DocumentBuilderFactory.newInstance().newDocumentBuilder() ;
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null ;
		}
	}

}
